// Lindsay Gilmour
// Adam Lusch
// Dan Niceswanger
//
// Computer Graphics Project 1:
// Asteroids!
// A Tribute

#include "PhysicsWorld.h"
#include <iostream>

int32 PhysicsWorld::bulletsFired = 0;
int32 PhysicsWorld::bulletsHit = 0;

PhysicsWorld::PhysicsWorld()
{
	scoring = false;
	
	messageTimer = displayTimer;
	
	worldAABB.lowerBound.Set(-100.0f, -100.0f);
	worldAABB.upperBound.Set(100.0f, 100.0f);

	doSleep = true;
	b2Vec2 gravity(0.0f, 0.0f);

	world = new b2World(worldAABB, gravity, doSleep);
	//debug.SetFlags(b2DebugDraw::e_shapeBit);
 	//world->SetDebugDraw(&debug);
	
	collisions = new CollisionHandler;
	world->SetContactListener(collisions);
}

PhysicsWorld::~PhysicsWorld()
{
	list<Thing*>::iterator iter = things.begin();
	for(; iter != things.end(); ++iter)
	{
		delete *iter;
	}

	delete world;
	delete collisions;

	glDeleteLists(lifeList, 1);
}

// Draw text at a specific location
void PhysicsWorld::drawText(float32 x, float32 y, string text)
{
	glPushMatrix();
		glColor3f(1.0f, 1.0f, 1.0f);
		glTranslatef(x, y, 0.0f);
		glScalef(0.01f, 0.01f, 0.01f);
		for (unsigned int i = 0; i < text.size(); i++)
		{
			glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, text[i]);
		}
	glPopMatrix();
}

void PhysicsWorld::spawnAlien()
{
	static const float32 rad = 5.0;

	if (level >= 2 && !ufo)
	{
		int32 numShapes;
		float32 x, y;
		
		float32 l = -25, r = 25, b = -25, t = 25;
		
		do
		{
			x = b2Random(l, r);
			y = b2Random(b, t);
			
			tester.lowerBound = b2Vec2(x - rad, y - rad);
			tester.upperBound = b2Vec2(x + rad, y + rad);
			
			numShapes = world->Query(tester, shapes, k_maxCount);
		}
		while (numShapes > 0);
	
		ufo = new Ufo(world, x, y);
		things.push_back(ufo);

		alienShootTimeout = (int32)b2Random(ALIEN_SHOOT_MIN, ALIEN_SHOOT_MAX);
	}
}

bool PhysicsWorld::spawnPlayer()
{
	static const float32 rad = 3.0;
	
	int32 numShapes;
	
	tester.lowerBound = b2Vec2(-rad, -rad);
	tester.upperBound = b2Vec2(rad, rad);

	numShapes = world->Query(tester, shapes, k_maxCount);
	
	if (numShapes > 0)
		return true;

	ship = new Ship(world);
	things.push_back(ship);

	return false;
}

void PhysicsWorld::spawnBullet()
{
	if (ship && !dead)
	{
		float32 angle = ship->getAngle() + M_PI/2.0;
		b2Vec2 pos = ship->getPosition();
		b2Vec2 vel = ship->getLinearVelocity();
		float32 distFromShip = 1.8;
	
		Bullet* bullet = new Bullet(world, pos.x + distFromShip*cos(angle), pos.y + distFromShip*sin(angle), angle, vel);
		things.push_back(bullet);
		bulletsFired++;
	}
}

void PhysicsWorld::spawnUfoBullet()
{
	if (ufo)
	{

		b2Vec2 pos = ufo->getPosition();
		float32 angle;
	
		if (playing && ship && !dead)
		{
			b2Vec2 playerPos = ship->getPosition();

			float32 x = abs(pos.x - playerPos.x);
			float32 y = abs(pos.y - playerPos.y);

			if (playerPos.x > pos.x)
			{
				if (playerPos.y > pos.y) // I
				{
					angle = atan2(y, x);
				}
				else // IV
				{
					angle = 2*M_PI - atan2(y, x);
				}
			}
			else
			{
				if (playerPos.y > pos.y) // II
				{
					angle = M_PI - atan2(y, x);
				}
				else // III
				{
					angle = M_PI + atan2(y, x);
				}
			}
		}
		else
		{
			angle = b2Random(0.0f, 2.0f * M_PI);
		}
		
		b2Vec2 vel = ufo->getLinearVelocity();
		float32 distFromShip = 1.8;
	
		AlienBullet* bullet = new AlienBullet(world, pos.x + distFromShip*cos(angle), pos.y + distFromShip*sin(angle), angle, vel);
		things.push_back(bullet);
	}
}

void PhysicsWorld::init()
{
	setUpLifeList();
	gameOver = false;
}

void PhysicsWorld::startGame()
{
	playing = true;
	dead = true;
	showingScores = false;

	list<Thing*>::iterator iter = things.begin();
	for(; iter != things.end(); ++iter)
	{
		delete *iter;
	}

	list<Particle*>::iterator piter = particles.begin();
	for(; piter != particles.end(); ++piter)
	{
		delete *piter;
	}

	ship = NULL;
	ufo = NULL;
	things.clear();
	particles.clear();

	level = 0;
	score = 0;
	lives = 3;
	numAsteroids = 0;
	alienTimeout = ALIEN_TIME;
	
	setupLevel();
	dead = spawnPlayer();
}

bool PhysicsWorld::isPlaying() const
{
	return playing;
}

bool PhysicsWorld::isScoring() const
{
	return scoring;
}

void PhysicsWorld::splashScreen()
{
	//scoring = false;
	playing = false;
	dead = true;
	showingScores = false;

	list<Thing*>::iterator iter = things.begin();
	for(; iter != things.end(); ++iter)
	{
		delete *iter;
	}

	list<Particle*>::iterator piter = particles.begin();
	for(; piter != particles.end(); ++piter)
	{
		delete *piter;
	}

	ship = NULL;
	ufo = NULL;
	things.clear();
	particles.clear();

	level = 1;
	score = 0;
	lives = 3;
	alienTimeout = ALIEN_TIME;
	
	setupLevel();
}

void PhysicsWorld::setupLevel()
{
	bulletsFired = 0;
	bulletsHit = 0;
	alienKills = 0;
	
	++level;
	if (level % 5 == 0)
	{
		lives++;
	}
	
	for (int i = 0; i < 4 + int32(level / 2.0f); i++)
	{
		addAsteroid(2.0);
	}

	alienTimeout = ALIEN_TIME;
}

void PhysicsWorld::addAsteroid(float32 scale)
{
	static const float32 rad = 1.0;
	
	int32 numShapes;
	float32 x, y;
	
	float32 l = -25, r = 25, b = -25, t = 25;
	
	do
	{
		x = b2Random(l, r);
		y = b2Random(b, t);
		
		tester.lowerBound = b2Vec2(x - rad, y - rad);
		tester.upperBound = b2Vec2(x + rad, y + rad);
		
		numShapes = world->Query(tester, shapes, k_maxCount);
	}
	while (numShapes > 0);
	
	Asteroid* asteroid = new Asteroid(world, x, y, scale);
	asteroid->move();
	
	things.push_back(asteroid);
	
	++numAsteroids;
}

void PhysicsWorld::setViewable(float32 l, float32 r, float32 b, float32 t)
{
	left = l;
	right = r;
	bottom = b;
	top = t;
}

void PhysicsWorld::moveOffscreenThing(Thing* thing)
{
	int32 numShapes;
	
	b2Vec2 pos = thing->getPosition();
	b2Vec2 vel = thing->getLinearVelocity();
	float32 rad = thing->getBoundingRadius();
		
	if (vel.x < 0 && pos.x + rad < left)
	{
		b2Vec2 target(right + rad, pos.y);
			
		do
		{
			tester.lowerBound = b2Vec2(target.x - rad, target.y - rad);
			tester.upperBound = b2Vec2(target.x + rad, target.y + rad);
				
			numShapes = world->Query(tester, shapes, k_maxCount);
			if (numShapes == 0)
			{
				break;
			}
				
			target.x -= vel.x;
			target.y -= vel.y;
		}
		while (numShapes > 0);
			
		thing->move(target);
	}
	else if (vel.x > 0 && pos.x - rad > right)
	{
		b2Vec2 target(left - rad, pos.y);
			
		do
		{
			tester.lowerBound = b2Vec2(target.x - rad, target.y - rad);
			tester.upperBound = b2Vec2(target.x + rad, target.y + rad);
				
			numShapes = world->Query(tester, shapes, k_maxCount);
			if (numShapes == 0)
			{
				break;
			}
				
			target.x -= vel.x;
			target.y -= vel.y;
		}
		while (numShapes > 0);
			
		thing->move(target);
	}
	else if (vel.y < 0 && pos.y + rad < bottom)
	{
		b2Vec2 target(pos.x, top + rad);
			
		do
		{
			tester.lowerBound = b2Vec2(target.x - rad, target.y - rad);
			tester.upperBound = b2Vec2(target.x + rad, target.y + rad);
				
			numShapes = world->Query(tester, shapes, k_maxCount);
			if (numShapes == 0)
			{
				break;
			}
				
			target.x -= vel.x;
			target.y -= vel.y;
		}
		while (numShapes > 0);
			
		thing->move(target);
	}
	else if (vel.y > 0 && pos.y - rad > top)
	{
		b2Vec2 target(pos.x, bottom - rad);
			
		do
		{
			tester.lowerBound = b2Vec2(target.x - rad, target.y - rad);
			tester.upperBound = b2Vec2(target.x + rad, target.y + rad);
				
			numShapes = world->Query(tester, shapes, k_maxCount);
			if (numShapes == 0)
			{
				break;
			}
				
			target.x -= vel.x;
			target.y -= vel.y;
		}
		while (numShapes > 0);
		
		thing->move(target);
	}
}

void PhysicsWorld::step(float32 timeStep, int32 iterations, int32* keys)
{	
	if (scoring)
	{
		glPushMatrix();
			glLineWidth(1.5f);
			drawText(-8.0f, 0.0f, "Please enter your name");
			drawText(-8.0f, -2.0f, name+"_");
		glPopMatrix();
		return;
	}	
		
	if (!ufo)
	{
		--alienTimeout;
	
		if (alienTimeout < 1)
		{
			spawnAlien();
		}
	}
	else
	{
		--alienShootTimeout;

		if (alienShootTimeout < 1)
		{
			spawnUfoBullet();
			alienShootTimeout = (int32)b2Random(ALIEN_SHOOT_MIN, ALIEN_SHOOT_MAX);
		}
	}
	

	if (numAsteroids < 1)
	{
		handleAchievements();
		
		setupLevel();
	}

	if (lives < 0)
	{
		gameOver = true;
		achievements.clear();
		saveScore();
	}

	if (playing && dead)
	{
		dead = spawnPlayer();
	}

	if (playing && ship && !dead)
	{
		bool rotating = false;
		if (keys[GLUT_KEY_LEFT])
		{
			ship->rotate(4*(M_PI/180.0));
			rotating = true;
		}
		
		if (keys[GLUT_KEY_RIGHT])
		{
			ship->rotate(-4*(M_PI/180.0));
			rotating = true;
		}
		
		if (!rotating)
		{
			ship->stopRotation();
		}
		
		if (keys[GLUT_KEY_UP])
		{
			ship->forward();
		}
		else
		{
			ship->stopThrust();
		}
	}
	
	world->Step(timeStep, iterations);
	
	Thing* t1;
	Thing* t2;
	set<Thing*> toDelete;

	bool playerKilledAlien = false;
	
	const map<int32, b2ContactPoint*>& contacts = collisions->getContacts();
	map<int32, b2ContactPoint*>::const_iterator contactIter = contacts.begin();
	for(; contactIter != contacts.end(); ++contactIter)
	{
		t1 = static_cast<Thing*>(contactIter->second->shape1->GetUserData());
		t2 = static_cast<Thing*>(contactIter->second->shape2->GetUserData());
		
		b2Vec2 pos = contactIter->second->position;
		float32 scale = contactIter->second->velocity.Length() / 80.0;
		
		for (int i = 0; i < 5; i++)
		{
			float32 x = b2Random(-scale, scale);
			float32 y = b2Random(-scale, scale);
			particles.push_back(new Particle(pos, b2Vec2(x, y)));
		}

		int32 magic1 = t1->getMagic();
		int32 magic2 = t2->getMagic();
		
		if(magic1 != magic2)
		{
			toDelete.insert(t1);
			toDelete.insert(t2);
		}

		if ((magic1 == Ufo::MAGIC_NUMBER && magic2 == Bullet::MAGIC_NUMBER)
			|| (magic1 == Bullet::MAGIC_NUMBER && magic2 == Ufo::MAGIC_NUMBER)
			|| (magic1 == Ufo::MAGIC_NUMBER && magic2 == Ship::MAGIC_NUMBER)
			|| (magic1 == Ship::MAGIC_NUMBER && magic2 == Ufo::MAGIC_NUMBER))
		{
			playerKilledAlien = true;
			alienKills++;
		}
	}
	
	list<Thing*>::iterator iter = things.begin();
	for(; iter != things.end(); ++iter)
	{
		Bullet* b = dynamic_cast<Bullet*>(*iter);
		if (b  && b->getTTL() <= 0)
		{
			toDelete.insert(*iter);
			continue;
		}
	}
	
	set<Thing*>::iterator delIter = toDelete.begin();
	for(; delIter != toDelete.end(); ++delIter)
	{
		Asteroid* a = dynamic_cast<Asteroid*>(*delIter);
		Ufo* u = dynamic_cast<Ufo*>(*delIter);
		
		if (*delIter == ship)
		{
			dead = spawnPlayer();
			delete *delIter;
			things.remove(*delIter);

			--lives;
		}
		else if (a)
		{
			b2Vec2 pos = a->getPosition();
			float32 bound = a->getBoundingRadius();
			float32 scale = a->getScale();

			score += (int32)((1 / scale) * 100);
			bulletsHit++;
			
			delete *delIter;
			things.remove(*delIter);
			
			--numAsteroids;
			
			if (scale > 0.5)
			{
				Asteroid* a1 = new Asteroid(world, pos.x - bound/2, pos.y, scale/2);
				a1->move();
				things.push_back(a1);
		
				Asteroid* a2 = new Asteroid(world, pos.x + bound/2, pos.y, scale/2);
				a2->move();
				things.push_back(a2);
				
				numAsteroids += 2;
			}
		}
		else if (u)
		{
			if (playerKilledAlien)
			{
				score += 500;
			}
			
			delete *delIter;
			things.remove(*delIter);
			ufo = NULL;
			alienTimeout = ALIEN_TIME;
		}
		else
		{
			delete *delIter;
			things.remove(*delIter);
		}
	}
	
	iter = things.begin();
	for(; iter != things.end(); ++iter)
	{
		moveOffscreenThing(*iter);
		(*iter)->draw();
	}
	
	set<Particle*> particlesToDelete;
	
	list<Particle*>::iterator piter = particles.begin();
	for(; piter != particles.end(); ++piter)
	{
		(*piter)->draw();
		
		if ((*piter)->getTTL() <= 0)
		{
			delete *piter;
			particles.erase(piter++);
		}
	}

	if (playing)
	{
		ostringstream scoreStream;
		scoreStream << score;
	
		glLineWidth(1.5f);
		drawText(left + 1.0f, top - 2.0f , scoreStream.str());
		drawLives();

		ostringstream levelStream;
		levelStream << "Lvl " << level;
	
		drawText(left + 1.0f, bottom + 1.0f , levelStream.str());
		
		if (messageTimer < displayTimer)
		{
			messageTimer++;
			list<string>::iterator aIter = achievements.begin();
			float32 j = -6.0f;
			for (; aIter != achievements.end(); aIter++)
			{
				glPushMatrix();
					glLineWidth(1.25f);
					glScalef(0.7f, 0.7f, 0.7f);
					drawText(-0.5f * (*aIter).length(), top - j, *aIter);
				glPopMatrix();
				j += 2.0f;
			}
		}
	}
	else
	{
		if (showingScores)
		{
			drawScores();
		}
		else	
			drawTitle();
	}

	if (playing && dead)
	{
		glLineWidth(1.5f);
		drawText(-18.0f, 0.0f , "Look out! There's an asteroid there!");
	}
}

void PhysicsWorld::drawLives()
{
	glPushMatrix();
		glTranslatef(left + 2.1f, top - 4.0f, 0.0f);
		glScalef(0.75f, 0.75f, 1.0f);

		for (int32 i = 0; i < lives; i++)
		{
			glPushMatrix();
				glTranslatef(4.0f * i, 0.0f, 0.0f);
				glCallList(lifeList);
			glPopMatrix();
		}
	glPopMatrix();	
}

void PhysicsWorld::drawTitle()
{
	if (gameOver)
	{
		glPushMatrix();
			glLineWidth(1.5f);
			glScalef(1.5f, 1.5f, 1.0f);
			drawText(-5.0f, 10.0f , "Game Over");
		glPopMatrix();
	}

	glPushMatrix();
		glLineWidth(3.0f);
		glScalef(3.0f, 3.0f, 1.0f);
		drawText(-5.0f, 0.0f , "Asteroids!");
	glPopMatrix();

	glPushMatrix();
		glLineWidth(1.5f);
		glScalef(1.5f, 1.5f, 1.0f);
		drawText(-5.0f, -2.0f , "A Tribute");
	glPopMatrix();

	glPushMatrix();
		glLineWidth(1.0f);
		drawText(-15.0f, -7.0f , "Lindsay Gilmour");
		drawText(-15.0f, -9.0f , "Adam Lusch");
		drawText(-15.0f, -11.0f , "Dan Niceswanger");
	glPopMatrix();

	glPushMatrix();
		glLineWidth(1.0f);
		drawText(-16.0f, -22.0f , "Press <Space> to start rockin'");
		drawText(-16.0f, -24.0f, "Press <h> to view high scores");
	glPopMatrix();
}

void PhysicsWorld::addLetter(unsigned char k)
{
	// range of valid ASCII characters
	if ( 32 <= (int)k && (int)k <= 122 )
	{
		if (name.length() < 16)
		{
			name += k;
		}
	}
	// backspace
	else if ((int)k == 8)
	{
		if (name.length() > 0)
		{
			// erase last character
			name.erase(name.end()-1);
		}
	}
	// return key
	else if ((int)k == 13)
	{
		ofstream scoreFile("high_scores", ios_base::app);
		if (scoreFile.is_open())
		{
			scoreFile << endl << name << endl << score;
		}
		scoreFile.close();
		scoring = false;
		splashScreen();
	}
}

void PhysicsWorld::getScores()
{
	// toggle showingScores
	showingScores = showingScores == true ? false : true;
	
	if (!showingScores)
		return;
	
	ifstream scoreFile("high_scores");
	if (scoreFile.is_open())
	{
		highScores.clear();
	
		string player;
		string s_score;
		stringstream buf;
		int n_score;
		
		// initial blank line
		getline(scoreFile, player);
		while (!scoreFile.eof())
		{
			getline(scoreFile, player);
			getline(scoreFile, s_score);
			buf.clear();
			buf << s_score;
			buf >> n_score;
			
			highScores.insert( pair<int,string>(n_score, player) );
		}
	}
	scoreFile.close();
}

void PhysicsWorld::drawScores()
{
	if  (highScores.size() > 0)
	{
		multimap<int, string>::iterator mapIter;
		
		int i = 1;
		float32 y = 8.0f;
		stringstream ss_score;
		string s_score;
		string pad_char;
		
		glPushMatrix();
			glLineWidth(1.5f);
			glScalef(2.0f, 2.0f, 2.0f);
			drawText(-7.5f, y-0.5f, "High Scores");
			drawText(-7.5f, y-0.5f, "___________");
		glPopMatrix();
		
		glPushMatrix();
			glLineWidth(1.25f);
			glScalef(1.5f, 1.5f, 1.5f);
			for (mapIter = highScores.begin(); mapIter != highScores.end(); mapIter++)
			{
				// clear stringstream
				ss_score.str("");
				ss_score << (*mapIter).first;
				s_score = ss_score.str();
				pad_char.clear();
				pad_char.append(17 - (*mapIter).second.length(), ' ');
				drawText(-10.0f, y, (*mapIter).second+pad_char+s_score);
				y -= 1.5f;
				if (i == 10)
					break;
				i++;
			}
		glPopMatrix();
		//return;
	}
	else
	{
		glPushMatrix();
			glLineWidth(1.5f);
			glScalef(2.0f, 2.0f, 2.0f);
			drawText(-8.5f, 4.0f, "No Scores Recorded!");
		glPopMatrix();
	}
}

void PhysicsWorld::saveScore()
{
	scoring = true;
	name.clear();
}

void PhysicsWorld::handleAchievements()
{
	achievements.clear();
	stringstream ach;
		
	// level completion achievement
	score += level * levelBonus;
	ach << "Level Complete Bonus: " << level*levelBonus << " points";
	achievements.push_back(ach.str());
		
	// extra life achievement
	if (level % 5 == 4)
	{
		score += level * extraLifeBonus;
		ach.str("");
		ach << "Extra Life Bonus: " << level * extraLifeBonus << " points";
		achievements.push_back(ach.str());
	}
	
	// marksman achievement
	float32 accuracy = 100 * (float32)bulletsHit/(float32)bulletsFired;
	if (accuracy > 75.0f) 
	{
		score += level * marksmanBonus;
		ach.str("");
		ach << "Marksman Bonus: " << level * marksmanBonus << " points";
		achievements.push_back(ach.str());
	}
	
	// predator achievement
	if (alienKills > 5)
	{
		score += level * predatorBonus;
		ach.str("");
		ach << "Predator Bonus: " << level * predatorBonus << " points";
		achievements.push_back(ach.str());
	}
		
	// diplomat achievement
	if (alienKills == 0 && level > 1)
	{
		score += level * diplomatBonus;
		ach.str("");
		ach << "Diplomat Bonus: " << level * diplomatBonus << " points";
		achievements.push_back(ach.str());
	}
		
	messageTimer = 0;
}

void PhysicsWorld::setUpLifeList()
{
	lifeList = glGenLists(1);
	glNewList(lifeList, GL_COMPILE);

	//TOP

	//border
	glColor3f(.75, .75, .75);
	glBegin(GL_LINE_STRIP);
	glVertex2f(-.1, 1.2);
	glVertex2f(-.2, 1.2);
	glVertex2f(-.3, .8);
	glVertex2f(-.16, 1.16);
	glVertex2f(-.1, 1.16);
	glEnd();
	
	glBegin(GL_LINE_STRIP);
	glVertex2f(0, 1.2);
	glVertex2f(.1, 1.2);
	glVertex2f(.2, .8);
	glVertex2f(.06, 1.16);
	glVertex2f(0, 1.16);
	glEnd();
	
	//window
	glColor3f(.75, .75, .75);
	glBegin(GL_LINES);
	glVertex2f(-.16, 1);
	glVertex2f(-.16, 1.16);
	glEnd();
	
	glBegin(GL_LINES);
	glVertex2f(.06, 1);
	glVertex2f(.06, 1.16);
	glEnd();
	
	//body
	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINE_STRIP);
	glVertex2f(-.1, 1.0);
	glVertex2f(-.16, 1.0);
	glVertex2f(-.3, .8);
	glVertex2f(.2, .8);
	glVertex2f(.06, 1.0);
	glVertex2f(0, 1.0);
	glEnd();
	
	//primary WEAPON
	glColor3f(.3, .3, .3);
	glBegin(GL_LINE_LOOP);
	glVertex2f(-.1, 1.3);
	glVertex2f(0, 1.3);
	glVertex2f(0, .9);
	glVertex2f(-.1, .9);
	glEnd();
	
	//MIDDLE
	
	//body
	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINE_LOOP);
	glVertex2f(-.2, .8);
	glVertex2f(-.4, .8);
	glVertex2f(-.4, 0);
	glVertex2f(-.2, 0);
	glEnd();
	
	glBegin(GL_LINE_LOOP);
	glVertex2f(.1, .8);
	glVertex2f(.3, .8);
	glVertex2f(.3, 0);
	glVertex2f(.1, 0);
	glEnd();
	
	//wings
	glColor3f(.75, .75, .75);
	glBegin(GL_LINE_STRIP);
	glVertex2f(-.4, .5);
	glVertex2f(-.5, .5);
	glVertex2f(-.7, .2);
	glVertex2f(-.4, .2);
	glEnd();
	
	glBegin(GL_LINE_STRIP);
	glVertex2f(.3, .5);
	glVertex2f(.4, .5);
	glVertex2f(.6, .2);
	glVertex2f(.3, .2);
	glEnd();
	
	//BOTTOM
	
	//body
	glColor3f(1.0, 1.0, 1.0);
	glBegin(GL_LINE_STRIP);
	glVertex2f(-.5, -.2);
	glVertex2f(-.5, 0);
	glVertex2f(.4, 0);
	glVertex2f(.4, -.2);
	glEnd();
	
	glBegin(GL_LINES);
	glVertex2f(-.2, -.5);
	glVertex2f(.1, -.5);
	glEnd();
	
	//burners
	glColor3f(.3, .3, .3);
	glBegin(GL_LINE_LOOP);
	glVertex2f(-.2, -.2);
	glVertex2f(-.6, -.2);
	glVertex2f(-.6, -.7);
	glVertex2f(-.2, -.7);	
	glEnd();

	glBegin(GL_LINE_LOOP);
	glVertex2f(.1, -.2);
	glVertex2f(.5, -.2);
	glVertex2f(.5, -.7);
	glVertex2f(.1, -.7);
	glEnd();
	
	//back wings
	glColor3f(.75, .75, .75);
	glBegin(GL_LINE_STRIP);
	glVertex2f(-.6, -.3);
	glVertex2f(-.9, -.3);
	glVertex2f(-1.2, -.6);
	glVertex2f(-1.3, -1.0);
	glVertex2f(-1.3, -1.3);
	glVertex2f(-.8, -.7);
	glVertex2f(-.6, -.7);
	glEnd();
	
	glBegin(GL_LINE_STRIP);
	glVertex2f(.5, -.3);
	glVertex2f(.8, -.3);
	glVertex2f(1.1, -.6);
	glVertex2f(1.2, -1.0);
	glVertex2f(1.2, -1.3);
	glVertex2f(.7, -.7);
	glVertex2f(.5, -.7);
	glEnd();
	
	glEndList();
}
